home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / cmyk.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  6KB  |  303 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    cmyk -
  19.  *        functions to support CMYK representations
  20.  *
  21.  *               Paul Haeberli - 1990
  22.  *
  23.  *    exports
  24.  *
  25.     void cmyksetup(uc,um,uy,uk,bl)
  26.     void vrgb_to_cmyk(rbuf,gbuf,bbuf,cbuf,mbuf,ybuf,kbuf,cortab,n)
  27.     void rgb_to_cmyk(r,g,b,c,m,y,k,cortab)
  28.     void rgb_to_cmyonly(r,g,b,c,m,y,k,cortab)
  29.     void rgb_to_konly(r,g,b,c,m,y,k,cortab)
  30.     void frgb_to_cmyk(r,g,b,c,m,y,k)
  31.     void getcmykrow(image,cmykbuf,iy,z)
  32.  *
  33.  */
  34. #include "math.h"
  35. #include "stdio.h"
  36. #include "image.h"
  37. #include "lum.h"
  38.  
  39. /*
  40.  *    rgb_to_cmyk -
  41.  *        Convert from rgb to cmyk.  This implements grey component
  42.  *    replacement. 
  43.  *
  44.  *    Inputs:
  45.  *        r intensity 0 to 255
  46.  *        g intensity 0 to 255
  47.  *        b intensity 0 to 255
  48.  *
  49.  *    Outputs:
  50.  *        c coverage 0 to 255
  51.  *        m coverage 0 to 255
  52.  *        y coverage 0 to 255
  53.  *        k coverage 0 to 255
  54.  *
  55.  *
  56.  *    An input value of rgb=[255,255,255] represents white.  When this is
  57.  *    transformed to cmyk, we get cmyk=[0,0,0,0] which represents zero 
  58.  *    coverage. 
  59.  *
  60.  *    An input value of rgb=[128,128,128] represents 50 percent grey.  When
  61.  *    this is transformed to cmyk, we get cmyk=[0,0,0,127] which represents 
  62.  *    zero coverage by cmy, and 50 percent coverage by black. 
  63.  *
  64.  */
  65. static int ultrac = 160;
  66. static int ultram = 160;
  67. static int ultray = 0;
  68. static int ultrak = 255;
  69. static int blacklerp = 4;
  70.  
  71. void cmyksetup(uc,um,uy,uk,bl)
  72. int uc, um, uy, uk, bl;
  73. {
  74.     ultrac = uc;
  75.     ultram = um;
  76.     ultray = uy;
  77.     ultrak = uk;
  78.     blacklerp = bl;
  79. }
  80.  
  81. void rgb_to_cmyk(r,g,b,c,m,y,k,cortab)
  82. int r, g, b;
  83. int *c, *m, *y, *k;
  84. short cortab[256];
  85. {
  86.     int i;
  87.     float param; 
  88.  
  89. /* i is the max of r, g, and b */
  90.     i = 0;
  91.     if(r>i)
  92.     i = r;
  93.     if(g>i)
  94.     i = g;
  95.     if(b>i)
  96.     i = b;
  97.  
  98. /* if r, g and b are all zero then print full k plus some m and c */
  99.     if(i == 0) {
  100.     *c = ultrac;
  101.     *m = ultram;
  102.     *y = ultray;
  103.     *k = ultrak;
  104.     return;
  105.     }
  106.     r = (255*r)/i;
  107.     g = (255*g)/i;
  108.     b = (255*b)/i;
  109.     if(cortab) {
  110.     *c = 255-cortab[r];
  111.     *m = 255-cortab[g];
  112.     *y = 255-cortab[b];
  113.     *k = 255-cortab[i];
  114.     } else {
  115.     *c = 255-r;
  116.     *m = 255-g;
  117.     *y = 255-b;
  118.     *k = 255-i;
  119.     }
  120.      
  121. /* if i is less than blacklerp start lerp towards ultra-black */
  122.     if(i<blacklerp) {
  123.     param = ((float)i)/((float)blacklerp);
  124.     *c = lerp(ultrac,*c,param);
  125.     *m = lerp(ultram,*m,param);
  126.     *y = lerp(ultray,*y,param);
  127.     *k = *k;
  128.     }
  129. }
  130.  
  131. void vrgb_to_cmyk(rbuf,gbuf,bbuf,cbuf,mbuf,ybuf,kbuf,cortab,n)
  132. short *rbuf,*gbuf,*bbuf;
  133. short *cbuf,*mbuf,*ybuf,*kbuf;
  134. short *cortab;
  135. int n;
  136. {
  137.     int c, m, y, k;
  138.  
  139.     while(n--) {
  140.     rgb_to_cmyk(*rbuf++,*gbuf++,*bbuf++,&c,&m,&y,&k,cortab);
  141.     *cbuf++ = c;
  142.     *mbuf++ = m;
  143.     *ybuf++ = y;
  144.     *kbuf++ = k;
  145.     }
  146. }
  147.  
  148. void rgb_to_cmyonly(r,g,b,c,m,y,k,cortab)
  149. int r, g, b;
  150. int *c, *m, *y, *k;
  151. short cortab[256];
  152. {
  153.     if(cortab) {
  154.     *c = 255-cortab[r];
  155.     *m = 255-cortab[g];
  156.     *y = 255-cortab[b];
  157.     } else {
  158.     *c = 255-r;
  159.     *m = 255-g;
  160.     *y = 255-b;
  161.     }
  162.     *k = 0;
  163. }
  164.  
  165. void rgb_to_konly(r,g,b,c,m,y,k,cortab)
  166. int r, g, b;
  167. int *c, *m, *y, *k;
  168. short cortab[256];
  169. {
  170.     int val; 
  171.  
  172.     val = ILUM(r,g,b);
  173.     *c = 0;
  174.     *m = 0;
  175.     *y = 0;
  176.     if(cortab)
  177.     *k = 255-cortab[val];
  178.     else
  179.     *k = 255-val;
  180. }
  181.  
  182. #define EPSILON    (0.0001)
  183.  
  184. /*
  185.  *    frgb_to_cmyk -
  186.  *        Convert from rgb to cmyk.  This implements grey component
  187.  *    replacement. 
  188.  *
  189.  *    Inputs:
  190.  *        r intensity 0 to 1.0
  191.  *        g intensity 0 to 1.0
  192.  *        b intensity 0 to 1.0
  193.  *
  194.  *    Outputs:
  195.  *        c coverage 0 to 255
  196.  *        m coverage 0 to 255
  197.  *        y coverage 0 to 255
  198.  *        k coverage 0 to 255
  199.  *
  200.  *
  201.  *    An input value of rgb=[1.0,1.0,1.0] represents white.  When this is
  202.  *    transformed to cmyk, we get cmyk=[0,0,0,0] which represents zero 
  203.  *    coverage. 
  204.  *
  205.  *    An input value of rgb=[0.5,0.5,0.5] represents 50 percent grey.  When
  206.  *    this is transformed to cmyk, we get cmyk=[0,0,0,127] which represents 
  207.  *    zero coverage by cmy, and 50 percent coverage by black. 
  208.  *
  209.  */
  210. void frgb_to_cmyk(r,g,b,c,m,y,k)
  211. float r, g, b;
  212. float *c, *m, *y, *k;
  213. {
  214.     int i;
  215.     float param; 
  216.  
  217. /* i is the max of r, g, and b */
  218.     i = 0;
  219.     if(r>i)
  220.     i = r;
  221.     if(g>i)
  222.     i = g;
  223.     if(b>i)
  224.     i = b;
  225.  
  226. /* if r, g and b are all zero then print full k plus some m and c */
  227.     if(i<EPSILON) {
  228.     *c = ultrac;
  229.     *m = ultram;
  230.     *y = ultray;
  231.     *k = ultrak;
  232.     return;
  233.     }
  234.     r = (255*r)/i;
  235.     g = (255*g)/i;
  236.     b = (255*b)/i;
  237.     *c = 255-r;
  238.     *m = 255-g;
  239.     *y = 255-b;
  240.     *k = 255-i;
  241.  
  242. /* if i is less than BLACKLERP start lerp towards ultra-black */
  243.     if(i<blacklerp) {
  244.     param = ((float)i)/((float)blacklerp);
  245.     *c = flerp((float)ultrac,*c,param);
  246.     *m = flerp((float)ultram,*m,param);
  247.     *y = flerp((float)ultray,*y,param);
  248.     *k = *k;
  249.     }
  250. }
  251.  
  252. static unsigned short *rbuf, *gbuf, *bbuf;
  253. static int bufxsize;
  254.  
  255. void getcmykrow(image,cmykbuf,iy,z)
  256. IMAGE *image;
  257. unsigned short *cmykbuf;
  258. int iy, z;
  259. {
  260.     int xsize, n;
  261.     unsigned short *rptr, *gptr, *bptr;
  262.     unsigned short *cmykptr;
  263.     int c, m, y, k;
  264.  
  265.     xsize = image->xsize;
  266.     if(!rbuf || xsize != bufxsize) {
  267.     if(rbuf) {
  268.         free(rbuf);
  269.         free(gbuf);
  270.         free(bbuf);
  271.     }
  272.     rbuf = (unsigned short *)mymalloc(xsize*sizeof(short));
  273.     gbuf = (unsigned short *)mymalloc(xsize*sizeof(short));
  274.     bbuf = (unsigned short *)mymalloc(xsize*sizeof(short));
  275.     bufxsize = xsize;
  276.     }
  277.     getrow(image,rbuf,iy,0%image->zsize);
  278.     getrow(image,gbuf,iy,1%image->zsize);
  279.     getrow(image,bbuf,iy,2%image->zsize);
  280.     rptr = rbuf;
  281.     gptr = gbuf;
  282.     bptr = bbuf;
  283.     cmykptr = cmykbuf;
  284.     n = xsize;
  285.     while(n--) {
  286.     rgb_to_cmyk(*rptr++,*gptr++,*bptr++,&c,&m,&y,&k,0);
  287.     switch(z) {
  288.         case 0:
  289.         *cmykptr++ = c;
  290.         break;
  291.         case 1:
  292.         *cmykptr++ = m;
  293.         break;
  294.         case 2:
  295.         *cmykptr++ = y;
  296.         break;
  297.         case 3:
  298.         *cmykptr++ = k;
  299.         break;
  300.     }
  301.     }
  302. }
  303.